﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;

namespace BoYuanCore.Framework.MemoryCache
{
    //参考 https://www.cnblogs.com/fanfan-90/p/12151924.html

    /// <summary>
    /// 实例化缓存接口ICaching
    /// </summary>
    public class MemoryCaching : ICachingProvider
    {
        /*
        1、安装程序集：System.Runtime.Caching 和 Microsoft.Extensions.Caching.Memory，如果是是Core MVC程序自带的Microsoft.AspNetCore.App包里已经涵盖了 Microsoft.Extensions.Caching.Memory，无需重复下载。

        2、在ConfigureService中注册内存缓存服务： services.AddMemoryCache();

        3、构造函数注入 IMemoryCache
        */


        private readonly Microsoft.Extensions.Caching.Memory.MemoryCache _myCache = new Microsoft.Extensions.Caching.Memory.MemoryCache(new MemoryCacheOptions());
        private readonly IConfiguration _configuration;
        private readonly int _cacheTime;//缓存时间(分钟)
        public MemoryCaching(IConfiguration configuration)
        {
            this._configuration = configuration;
            
            _cacheTime = 60; //this._configuration.GetValue<int>("CACHE_TIME");
        }

        public void Dispose()
        {
            this._myCache?.Dispose();
        }

        public T GetOrSetObjectFromCache<T>(string cacheItemName, Func<T> objectSettingFunction, int cacheTimeInMinutes = 0)
        {
            T cacheObject = default(T);

            var cacheObj = this._myCache.Get(cacheItemName);
            if (cacheObj != null)
            {
                cacheObject = (T)cacheObj;
            }
            else
            {
                cacheObject = objectSettingFunction();
                this._myCache.Set(cacheItemName, cacheObject, DateTime.Now.AddMinutes(cacheTimeInMinutes == 0 ? _cacheTime : cacheTimeInMinutes));
            }
            return cacheObject;
        }

        public void SetValueToCache(string key, object value, int cacheTimeInMinutes = 120)
        {
            this._myCache.Set(key, value, DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes));
        }


        public object GetValueFromCache(string key)
        {
            return this._myCache.Get(key);
        }

        public void Remove(string key)
        {
            this._myCache.Remove(key);
        }

        public void RemoveAll()
        {
            var field = typeof(Microsoft.Extensions.Caching.Memory.MemoryCache).GetProperty("EntriesCollection", BindingFlags.NonPublic | BindingFlags.Instance);
            if (field != null)
            {
                if (field.GetValue(this._myCache) is ICollection collection)
                    foreach (var item in collection)
                    {
                        var methodInfo = item.GetType().GetProperty("Key");
                        if (methodInfo != null)
                        {
                            var val = methodInfo.GetValue(item);
                            this._myCache.Remove(val?.ToString());
                        }
                    }

            }
        }

    }



}
